//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//
//------------------------------------------------------------------------------
//
//  File:  kitl.c
//
//  Support routines for KITL. 
//
//  Note: this routines are stubbed out in the kern image.
//
//------------------------------------------------------------------------------

#include <bsp.h>
#include <kitl_cfg.h>
#include <devload.h>
#include "ISRAM.h"
#include "pmic_power.h"

BOOL OALKitlStart()
{
    BOOL rc = FALSE;
    OAL_KITL_ARGS *pKITLArgs, KITLArgs;
    CHAR *pszDeviceId;

    //OALLogSetZones((UINT32)0x8100000F); //A place to change OAL Debug Zones
    //KITLSetDebug(0xFFFFFFFF);

    OALMSG(OAL_KITL&&OAL_FUNC, (L"+OALKitlStart\r\n"));

    // Look for bootargs left by the bootloader or left over from an earlier boot.
    //
    pKITLArgs   = (OAL_KITL_ARGS*) OALArgsQuery(OAL_ARGS_QUERY_KITL);
    pKITLArgs->devLoc.LogicalLoc=(DWORD)pKITLArgs->devLoc.PhysicalLoc;

#ifdef BSP_BOOT_NOARGS
    pKITLArgs->ipAddress= inet_addr("192.168.55.101");//0x6537A8C0;
    pKITLArgs->ipMask=inet_addr("255.255.255.0");//0x00FFFFFF;
    pKITLArgs->ipRoute=0x0;
    //pKITLArgs->flags=OAL_KITL_FLAGS_ENABLED | OAL_KITL_FLAGS_POLL;
    pKITLArgs->flags=OAL_KITL_FLAGS_ENABLED;
    pKITLArgs->devLoc.BusNumber =0;
    pKITLArgs->devLoc.PhysicalLoc=(PVOID)(MONAHANS_BASE_REG_PA_USB2H);
    pKITLArgs->devLoc.LogicalLoc=(DWORD)pKITLArgs->devLoc.PhysicalLoc;
    pKITLArgs->devLoc.IfcType= Internal;
#endif

    //Dump Results
    NKDbgPrintfW(L"dumping PKITLArgs\r\n");
    NKDbgPrintfW(TEXT("pKITLArgs->flags is %x\r\n"), pKITLArgs->flags);
    NKDbgPrintfW(TEXT("pKITLArgs->ipAddress is %x\r\n"), pKITLArgs->ipAddress);
    NKDbgPrintfW(TEXT("pKITLArgs->route is %x\r\n"),pKITLArgs->ipRoute);
    NKDbgPrintfW(TEXT("pKITLArgs->devLoc.LogicalLoc; is %x\r\n"), pKITLArgs->devLoc.LogicalLoc);
    NKDbgPrintfW(TEXT("pKITLArgs->devLoc.PhysicalLoc is %x\r\n"), pKITLArgs->devLoc.PhysicalLoc);
    NKDbgPrintfW(TEXT("pKITLArgs->devLoc.IfcType is %x\r\n"),pKITLArgs->devLoc.IfcType);
    
    pszDeviceId = (CHAR*) OALArgsQuery(OAL_ARGS_QUERY_DEVID);\
    NKDbgPrintfW(TEXT("Kitl Device ID is %s\r\n"),pszDeviceId );
    
    // If no KITL arguments were found (typically provided by the bootloader), then select
    // some default settings.
    //
    if (pKITLArgs == NULL)
    {
        memset(&KITLArgs, 0, sizeof(OAL_KITL_ARGS));
        // By default, enable: KITL, DHCP, and VMINI...
        KITLArgs.flags = (OAL_KITL_FLAGS_ENABLED | OAL_KITL_FLAGS_DHCP | OAL_KITL_FLAGS_VMINI);
        // Use built-in LAN91C111 controller for KITL.
        KITLArgs.devLoc.IfcType     = Internal;
        KITLArgs.devLoc.BusNumber   = 0;
        KITLArgs.devLoc.PhysicalLoc = (PVOID)(MONAHANS_BASE_REG_PA_USB2H);
        KITLArgs.devLoc.LogicalLoc  = (DWORD)KITLArgs.devLoc.PhysicalLoc;

        pKITLArgs = &KITLArgs;
    }

    if (pszDeviceId == NULL)
    {
        OALMSG(OAL_ERROR, (L"ERROR: Unable to locate Device ID buffer\r\n"));
    }
    else if (pszDeviceId[0] == '\0')
    {
        // We don't yet have the Ethernet controller's MAC address (this is obtained
        // in the initialization function.  Store a base name for the device, and
        // signal that it should be extended with the MAC address later.
        //
        strncpy(pszDeviceId, BSP_DEVICE_PREFIX, OAL_KITL_ID_SIZE);
        pKITLArgs->flags |= OAL_KITL_FLAGS_EXTNAME;
    }
    else
    {
        OALMSG(1, (TEXT("DeviceID = %s\r\n"), pszDeviceId));
    }
    if(KITLArgs.devLoc.PhysicalLoc == (PVOID)MONAHANS_BASE_REG_PA_USB2H )
    {
        RegisterPowerDomainFunctions(EnableSRAMPowerDomain, DisableSRAMPowerDomain);
        EnableSRAM();
    }
        
        
    // Finally call KITL library.
    //
    rc = OALKitlInit(pszDeviceId, pKITLArgs, g_kitlDevices);

    OALMSG(OAL_KITL&&OAL_FUNC, (L"-OALKitlStart(rc = %d)\r\n", rc));
    return(rc);
}


DWORD OEMEthGetSecs (void)
{
    SYSTEMTIME st;
    DWORD dwRet;
    static DWORD dwBias;
    static DWORD dwLastTime;

    OEMGetRealTime( &st );
    dwRet = ((60UL * (60UL * (24UL * (31UL * st.wMonth + st.wDay) + st.wHour) + st.wMinute)) + st.wSecond);
    dwBias = dwRet;

    if (dwRet < dwLastTime) {
        KITLOutputDebugString("! Time went backwards (or wrapped): cur: %u, last %u\n",
                              dwRet,dwLastTime);
    }
    dwLastTime = dwRet;
    return (dwRet);
}


//------------------------------------------------------------------------------
//
//  Function:  Lan91CPowerOn
//
//  This function adds suspend/resume support to the common Microsoft LAN91C 
//  KITL driver. Common implementation assumes LAN91C stays on during
//  suspend/resume, which is not true on Littleton.
//
void LAN91CPowerOn()
{
    OAL_KITL_ARGS *pKITLArgs;
      
    pKITLArgs = (OAL_KITL_ARGS*) OALArgsQuery(OAL_ARGS_QUERY_KITL);
    pKITLArgs->devLoc.LogicalLoc = (DWORD) pKITLArgs->devLoc.PhysicalLoc;
    
    // On Littleton, the LAN91C111 daughter card loses power on suspend
    // We should do a full re-init.
    LAN91CInit( (UCHAR*) pKITLArgs->devLoc.PhysicalLoc, 
                         pKITLArgs->devLoc.LogicalLoc,
                         pKITLArgs->mac );
}


//------------------------------------------------------------------------------
//
//  Function:  OALGetTickCount
//
//  This function is called by some KITL libraries to obtain relative time
//  since device boot. It is mostly used to implement timeout in network
//  protocol.
//

UINT32 OALGetTickCount()
{
    return OEMEthGetSecs () * 1000;
}

VOID ReInitKITL()
{
#ifndef BSP_NOUSBKITL
    KITLTRANSPORT Kitl;

    OEMKitlInit(&Kitl);
#endif	
}

//------------------------------------------------------------------------------

